/*
 * Copyright (c) 2019, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2019-08-26     sogwms       The first version
 */

#include "single_pwm_motor.h"

static csi_gpio_pin_t PIN1;
static csi_gpio_pin_t PIN2;

static unsigned long single_pwm_motor_enable(void *mot)
{
    single_pwm_motor_t mot_sub = (single_pwm_motor_t)mot;

    rvm_hal_pwm_start(mot_sub->pwm_dev, mot_sub->channel);

    return 0;
}

static unsigned long single_pwm_motor_disable(void *mot)
{
    single_pwm_motor_t mot_sub = (single_pwm_motor_t)mot;

    rvm_hal_pwm_stop(mot_sub->pwm_dev, mot_sub->channel);

    return 0;
}

static unsigned long single_pwm_motor_reset(void *mot)
{
    return 0;
}

static unsigned long single_pwm_motor_set_speed(void *mot, signed short percentage)
{
    rvm_hal_pwm_config_t config;
    single_pwm_motor_t mot_sub = (single_pwm_motor_t)mot;

    float temp_percentage = percentage *0.01;

    if (temp_percentage == 0)
    {
        config.duty_cycle = 0;
        config.freq       = MOTOR_PWM_PERIOD;
        config.polarity   = RVM_HAL_PWM_POLARITY_NORMAL;
        rvm_hal_pwm_config(mot_sub->pwm_dev, &config, mot_sub->channel);

        csi_gpio_pin_write(&(*mot_sub).pin1, GPIO_PIN_LOW);
        csi_gpio_pin_write(&(*mot_sub).pin2, GPIO_PIN_LOW);
    }
    else
    {
        if (temp_percentage < 0)
        {
            temp_percentage = -temp_percentage;
            csi_gpio_pin_write(&(*mot_sub).pin1, GPIO_PIN_HIGH);
            csi_gpio_pin_write(&(*mot_sub).pin2, GPIO_PIN_LOW);
        }
        else
        {
            csi_gpio_pin_write(&(*mot_sub).pin1, GPIO_PIN_LOW);
            csi_gpio_pin_write(&(*mot_sub).pin2, GPIO_PIN_HIGH);
        }
        config.duty_cycle = temp_percentage;
        config.freq       = MOTOR_PWM_PERIOD;
        config.polarity   = RVM_HAL_PWM_POLARITY_NORMAL;
        rvm_hal_pwm_config(mot_sub->pwm_dev, &config, mot_sub->channel);
    }

    return 0;
}

single_pwm_motor_t single_pwm_motor_create(char *pwm, int channel, pin_name_t pin1, pin_name_t pin2)
{

    rvm_pwm_drv_register(0);

    single_pwm_motor_t new_motor = (single_pwm_motor_t)motor_create(sizeof(struct single_pwm_motor));
    if (new_motor == NULL)
    {
        return NULL;
    }
    
    new_motor->pwm_dev = (rvm_dev_t *)rvm_hal_pwm_open(pwm); ;
    if (new_motor->pwm_dev == NULL)
    {
        free(new_motor);
        aos_cli_printf("Falied to find device on %s", pwm);
        return NULL;
    }
    new_motor->channel = channel;
    new_motor->mot.enable = single_pwm_motor_enable;
    new_motor->mot.disable = single_pwm_motor_disable;
    new_motor->mot.reset = single_pwm_motor_reset;
    new_motor->mot.set_speed = single_pwm_motor_set_speed;

    csi_gpio_pin_init(&(*new_motor).pin1, pin1);
    csi_gpio_pin_init(&(*new_motor).pin2, pin2);

    csi_gpio_pin_mode(&(*new_motor).pin1, GPIO_MODE_PUSH_PULL);
    csi_gpio_pin_mode(&(*new_motor).pin2, GPIO_MODE_PUSH_PULL);

    csi_gpio_pin_dir(&(*new_motor).pin1, GPIO_DIRECTION_OUTPUT);
    csi_gpio_pin_dir(&(*new_motor).pin2, GPIO_DIRECTION_OUTPUT);  

    return new_motor;
}
